﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AGrandVenture
{
    static class SeedUtility
    {
        public static Random random = new Random(DateTime.Now.Millisecond);
        public static UInt64 WorldSeed = NextUInt64(random);

        /// <summary>
        /// Creates a seed with no "level" defined
        /// </summary>
        /// <returns>Seed with random level</returns>
        public static UInt64 newLevelessSeed()
        {
            return NextUInt64(random);
        }

        /// <summary>
        /// Creates a seed with a defined level
        /// </summary>
        /// <param name="level">Level of seed</param>
        /// <returns>A seed of the requested level</returns>
        public static UInt64 newSeed(int level)
        {
            UInt64 seed = NextUInt64(random);
            seed %= 100000000000000000;
            seed += (UInt64)(level * 100000000000000000);
            return seed;
        }

        //Helper function to generate random UInt64
        private static UInt64 NextUInt64(this Random rnd)
        {
            var buffer = new byte[sizeof(UInt64)];
            rnd.NextBytes(buffer);
            return BitConverter.ToUInt64(buffer, 0);
        }
        
        /// <summary>
        /// Returns the numeric value of a portion of a seed if read sequential starting at startRange and ending at endRange.
        /// </summary>
        /// <param name="startRange">First digit to start reading at</param>
        /// <param name="endRange">Last digit to end on</param>
        /// <param name="Seed">UInt64 of random information</param>
        /// <returns>Numeric value of seed portion if read in aggregate</returns>
        public static int getSeedValue(int startRange, int endRange, UInt64 Seed)
        {
            //Fix params passed in incorrect order
            if (startRange > endRange)
            {
                return int.Parse(Seed.ToString().Substring(endRange, startRange - endRange));
            }
            else
                return int.Parse(Seed.ToString().Substring(startRange, endRange - startRange));
        }

        public static int getSeedLevel(UInt64 Seed)
        {
            string sSeed = Seed.ToString();
            if (sSeed.Length < 19)
                sSeed = sSeed.PadLeft(19, '0');
            return int.Parse(sSeed.Substring(0, 2));
        }

        /// <summary>
        /// Sum of digits/digit pairs as defined by parameters
        /// </summary>
        /// <param name="startRange">First digit in sequence of pairs</param>
        /// <param name="endRange">Last digit in sequence of pairs</param>
        /// <param name="pairLength">Number of digits in each pair</param>
        /// <param name="Seed">UInt64 of random information</param>
        /// <returns>Sum of digits</returns>
        public static int getSumOfDigits(int startRange, int endRange, int pairLength, UInt64 Seed)
        {
            //Fix params passed in incorrect order
            if (startRange > endRange)
            {
                int x = startRange;
                startRange = endRange;
                endRange = x;
            }

            int sum = 0;
            for (int i = startRange; i < endRange; )
            {
                sum += int.Parse(Seed.ToString().Substring(i, i+pairLength));
                i += pairLength;
            }
            return sum;
        }

        /// <summary>
        /// Returns the numeric value of "##" where the 1st # is firstDigit and the 2nd # is secondDigit
        /// </summary>
        /// <param name="firstDigit">First digit of number return</param>
        /// <param name="secondDigit">Second digit of number return</param>
        /// <param name="Seed">UInt64 of random information</param>
        /// <returns>Value of digits specified if read in aggregate</returns>
        public static int getSeedPair(int firstDigit, int secondDigit, UInt64 Seed)
        {
            string sSeed = Seed.ToString();
            if (firstDigit > secondDigit)
                return int.Parse(sSeed.Substring(secondDigit - 1, 1) + sSeed.Substring(firstDigit - 1, 1));
            else
                return int.Parse(sSeed.Substring(firstDigit - 1, 1) + sSeed.Substring(secondDigit - 1, 1));
        }
    }
}
